﻿using CocoaAni.Net.WebSockets.Server.ArgAdapters.Base;
using CocoaAni.Net.WebSockets.Server.Attributes;
using CocoaAni.Net.WebSockets.Server.DefineInfos;
using CocoaAni.Net.WebSockets.Server.Exceptions;
using Newtonsoft.Json.Linq;

namespace CocoaAni.Net.WebSockets.Server.ArgAdapters;

public class JsonObjectPropertiesArgAdapter : MessageArgAdapter<object, JsonPropArgAttribute>
{
    public override object? GetTargetParameter(MessageArgContext argContext)
    {
        var context = argContext.WebSocketContext;
        var defineInfo = argContext.ArgDefineInfo;
        if (!context.Message.IsText)
        {
            if (!defineInfo.IsRequired)
            {
                return null;
            }
            throw new WebSocketMessageArgException
                ($"Arg:{defineInfo.Name} IsRequired And Must Use Text Message!",argContext.WebSocketContext);
        }

        var jsonObject = argContext.JsonObject;
        if (jsonObject == null)
        {
            if (defineInfo.IsRequired)
                throw new WebSocketMessageArgException($"Arg:{defineInfo.Name} IsRequired And Json Format Error! {argContext.JsonException?.Message}",argContext.JsonException,argContext.WebSocketContext);
            else return null;
        }
        
        try
        {
            if (jsonObject.ContainsKey(defineInfo.Name))
                return jsonObject.GetValue(defineInfo.Name).ToObject(defineInfo.Type);
        }
        catch (Exception e)
        {
            if (argContext.ArgDefineInfo.IsRequired)
            {
                throw new WebSocketMessageArgException
                    ($"Arg:{defineInfo.Name} IsRequired But Json Format Error", e, argContext.WebSocketContext);
            }
            return null;
        }

        if (!defineInfo.IsRequired)
        {
            return null;
        }
        throw new WebSocketMessageArgException
            ($"Arg:{defineInfo.Name} IsRequired But In Json Not Found!",argContext.WebSocketContext);
    }
}